package cn.edu.nju.ws.sview.reasoning.test;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;

import cn.edu.nju.ws.sview.rdf.RDFFactory;
import cn.edu.nju.ws.sview.rdf.ResourceFactory;
import cn.edu.nju.ws.sview.rdf.URIResource;
import cn.edu.nju.ws.sview.reasoning.Atom;
import cn.edu.nju.ws.sview.reasoning.Constant;
import cn.edu.nju.ws.sview.reasoning.GroundAtom;
import cn.edu.nju.ws.sview.reasoning.KnowledgeBase;
import cn.edu.nju.ws.sview.reasoning.Predicate;
import cn.edu.nju.ws.sview.reasoning.ProductionMemory;
import cn.edu.nju.ws.sview.reasoning.Rule;
import cn.edu.nju.ws.sview.reasoning.Term;
import cn.edu.nju.ws.sview.reasoning.Variable;
import cn.edu.nju.ws.sview.reasoning.WorkingMemory;
import cn.edu.nju.ws.sview.reasoning.provenance.FromSchemaReasoning;
import cn.edu.nju.ws.sview.reasoning.provenance.ProvenanceFactory;

import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;

public class test4 {
	//type = 0 constant, type = 1 variable
	public static Atom<Term> createAtom(int arity,String predSymbol,int[] types,String[] values) throws SQLException{
		Predicate predicate = new Predicate(ResourceFactory.getInstance().createURIResource("test4/"+predSymbol),arity);
		ArrayList<Term> list = new ArrayList<Term>();
		for(int i=0;i<arity;i++){
			String value = values[i];
			Term term;
			if(types[i]==0){
				 term = new Constant(ResourceFactory.getInstance().createURIResource("test4/"+value));
			}else{
				term = new Variable(value) ;
			}
			list.add(term) ;
		}
		Atom<Term> atom = new Atom<Term>(predicate,list);
		return atom;
	}
	public static void main(String[] args) throws SQLException{
		OntModel model = ModelFactory.createOntologyModel();	
	 	WorkingMemory wm =new WorkingMemory();
    	ProductionMemory pm = new ProductionMemory();
    	//Facts   p('a','b'),p('b','c'),p('d','e'),p('c','d'),p('c','f')
    	String[] fPredSymbol = {"p","p","p","p","p"};
    	String[] fFirst = {"a","b","d","c","c"} ;
    	String[] fSecond = {"b","c","e","d","f"};
    	HashSet<GroundAtom> facts = new HashSet<GroundAtom>();
    	for(int i = 0;i<5;i++){
    	    URIResource pred = ResourceFactory.getInstance().createURIResource("test4/"+fPredSymbol[i]);
    	    URIResource arg1 =  ResourceFactory.getInstance().createURIResource("test4/"+fFirst[i]);
    	    URIResource arg2 =  ResourceFactory.getInstance().createURIResource("test4/"+fSecond[i]);
    	    Constant s1 = new Constant(arg1);
    	    Constant s2 = new Constant(arg2);
    	    ArrayList<Constant> list = new ArrayList<Constant>();
    	    list.add(s1) ;
    	    list.add(s2) ;
    	    Predicate predicate = new Predicate(pred,2);
    	    GroundAtom fact = new GroundAtom(predicate,list,ProvenanceFactory.getInstance().createProvFromDataMembers());
    	    facts.add(fact);
    	}
    	//rules  ANS(?x,?y):-p(?x,?y), ANS(?x,?y):-ANS(?x,?z),p(?z,?y)
    	ArrayList<Atom<Term>> bodyList1 = new ArrayList<Atom<Term>>();
    	long startTime = System.currentTimeMillis();
    	     int[] types = {1,1};
    	     String[] values = {"x","y"};
    	     Atom<Term> headAtom1 = createAtom(2,"ANS",types,values);    
    	     String[][] bvalues = {{"x","z"},{"z","y"}};
    	     String[] preds = {"ANS","p"};
    	     int[] types3={1,1};
    	     int[] types4={1,1};
    	     for(int i=0;i<2;i++){
    	    	 if(i==0){
    	     		Atom<Term> atom = createAtom(2,preds[i],types3,bvalues[i]);
    	     		bodyList1.add(atom);
    	    	 }
    	    	 if(i==1){
     	     		Atom<Term> atom = createAtom(2,preds[i],types4,bvalues[i]);
     	     		bodyList1.add(atom);
     	    	 }
    	     }
    	     Rule rule1 = new  Rule(headAtom1,bodyList1,new FromSchemaReasoning());
    	     pm.addRule(rule1) ;
    	     
    	      ArrayList<Atom<Term>> bodyList2 = new ArrayList<Atom<Term>>();
    	     int[] types2 = {1,1};
    	     String[] values2 = {"x","y"};
    	     Atom<Term> headAtom2 = createAtom(2,"ANS",types2,values2);    
    	     String[][] bvalues2 = {{"x","y"}};
    	     String[] preds2 = {"p"};
    	     for(int i=0;i<1;i++){
    	     		Atom<Term> atom = createAtom(2,preds2[i],types2,bvalues2[i]);
    	     		bodyList2.add(atom);
    	     }
    	     Rule rule2 = new  Rule(headAtom2,bodyList2,new FromSchemaReasoning());
    	     pm.addRule(rule2) ;
    	     
    	      System.out.println("[INFO]loading rules completes");
     /**new a knowledge base**/
       KnowledgeBase kb = new KnowledgeBase(wm,pm);
      	for(GroundAtom atom:facts){
    		kb.addFact(atom) ;
    	}
/*Add a query ANS('a',?x)* answer: ('a','b'),('a','c'),('a','d'),('a','f'),('a','e')*/
       int[] x ={0,1};
       String[] y = {"a","y"};
    	Atom<Term> q = createAtom(2,"ANS",x,y);
	    HashSet<GroundAtom> ans= kb.Evaluate(q,true) ;
	    long endTime =System.currentTimeMillis();
	    long time = endTime - startTime;
//	    System.out.println("total time "+time);
//	    System.out.println("Query "+q.toString()+"\n");
		   System.out.println("Answer:\n ");
		   for(GroundAtom fact:ans){
			   System.out.println(fact.toString());
		   }
//		   System.out.println(kb.toString());
	}
}
